import { computed, reactive, watch, ref, unref } from 'vue';
import { omit } from 'lodash-es';
import { componentMap } from './componentMap';
import { isString, isUndefined, isBoolean, isFunction } from '@multi-kit/inspect';


function cutPrefix(target: String, prefix: string = ''): String {
  const regex = new RegExp(`^${prefix}(.+)$`);
  return target.replace(regex, (_, rest) => {
    // 把去掉 bind 后的首字母转小写
    return rest.charAt(0).toLowerCase() + rest.slice(1);
  });
}

/**
 * 转发表单输入组件的事件到form schema中
 * @param target {Object} 转发目标schema
 * @param formState { ref | reactive } formModal
 * @returns {Object}
 */
function transmitEvent(formState, target = {}): Object {
  // eslint-disable-next-line array-callback-return
  const obj = Object.keys(target).reduce((prev, key: string) => {
    if (/^on[A-Z]{1}\w+/.test(key)) {
      prev[key] = function (...args: any[]) {
        target[key](formState, ...args);
      };
    } else if (/^bind[A-Z]{1}\w+/.test(key)) {
      const newKey = cutPrefix(key, 'bind')
      prev[newKey] = function (...args: any[]) {
        target[key](formState, ...args);
      };
    }
    else {
      prev[key] = target[key];
    }

    return prev;
  }, {});
  return obj;
}

export function useFormItemState({ props }) {

  const { component } = props;
  const getFormItemProps = computed(() => {
    return omit(props, ['component']);
  });
  const getComponent = computed(() => {
    const comp = isString(component) ? componentMap[component] : component;
    return comp;
  });

  const getComponentProps = computed(() => {
    
    const componentProps = transmitEvent(
      props.formState,
      props?.componentProps
    );

    // TODO: placeholder在 select checkbox radio等选择组件中文案不合适需修改
    return {
      placeholder: `请您输入${props.label}`,
      ...componentProps,
    };
  });

  const modelValueType = computed<string>(() => {
    const { componentProps } = props;
    const isCheck =
      isString(component) &&
      ['Checkbox', 'Radio', 'Switch'].includes(component);
    const isUpload = component === 'Upload';
    return {
      true: 'value',
      [`${isCheck}`]: 'checked',
      [`${isUpload}`]: 'file-list',
    }.true;
  });

  const getSchemaCol = computed(() => {
    const show = props?.vIf ? props.vIf(props.formState) : true;

    return {
      show,
    };
  });

  watch(props.formState, (value) => {
    if (props?.vIf) {
      getSchemaCol.value.show = props.vIf(props.formState);
      console.log(
        'getSchemaCol.value.show',
        getSchemaCol.value.show,
        props.vIf(props.formState),
        props.name
      );
    } else {
      getSchemaCol.value.show = true;
    }
  });

  const getColProps = computed<{ span: number }>(() => {
    const { span } = props;
    return {
      span,
    };
  });

  const getShow = computed<{ isShow: boolean; isIfShow: boolean }>(() => {
    const { vShow, vIf, formState } = unref(props);
    let isShow = true;
    if (isBoolean(vShow)) {
      isShow = vShow;
    } else if (isFunction(vShow)) {
      isShow = vShow(formState);
    } else {
      isShow = true;
    }

    let isIfShow = true;

    if (isBoolean(vIf)) {
      isIfShow = vIf;
    } else if (isFunction(vIf)) {
      isIfShow = vIf(formState);
    } else {
      isIfShow = true;
    }
    return {
      isShow,
      isIfShow,
    };
  });

  return {
    getFormItemProps,
    getComponent,
    getComponentProps,
    getSchemaCol,
    getColProps,
    getShow,
  };
}
